/*
 * Serveur
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <arpa/inet.h>

/*
 * Port local du serveur
 * 
*/ 
#define SIZE 100

int main (int argc, char* argv[])
{
	/*
	 * sockfd: descripteur de socket
	 * client: structure d'adresse du client
	 * serveur: structure d'adresse du serveur
	 * len_serveur: taille de l'adresse du serveur
	 * len_client: taille de l'adresse du client
	 */
	 
	 int PORT = 9600;
	 char host[16];
	 int len_server = 0, len_client = 0;
	 int sockfd = 0, client_sockfd;
	 struct sockaddr_in client, server;
	 pid_t pid_fils;
	 
	 bzero(host, sizeof(host));
	 strcpy (host, "127.0.0.1");
	 
	 
	if (argc == 2)
		PORT = atoi(argv[1]);
	else if (argc == 3)
	{
		strcpy (host, argv[1]);	
		PORT = atoi(argv[2]);
	}
	
	 
	
	// ouvrir le socket du serveur
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	
	// remplir l'adresse local du serveur
	server.sin_family = AF_INET;
	server.sin_port = PORT;
	server.sin_addr.s_addr = inet_addr(host);
	
	len_server = sizeof (server);
	
	bind (sockfd, (struct sockaddr *)(&server), len_server);	
	listen (sockfd, 100);
	
    printf("HOST: %s --- PORT: %i\nserver waiting ... \n", host, PORT);

	while (1)
	{

    len_client = sizeof(client);
    client_sockfd = accept(sockfd, (struct sockaddr *)(&client), (socklen_t *)(&len_client));
    pid_fils = fork ();
    
    if (pid_fils == -1)
    {
		fprintf (stderr, "Erreur fork \n");
		return -1;
	}	
    else if (pid_fils == 0)
    {
		char sv[SIZE] = "ok";
		char cl[SIZE] = "";
		struct sockaddr_in adress;
		socklen_t  len_adress;
		
		//close (sockfd);
		//chat avec server
	    
		len_adress = sizeof(struct sockaddr_in);
		if (getpeername(client_sockfd, (struct sockaddr*) &adress, &len_adress) < 0)
		{
			fprintf(stderr, "Erreur getpeername\n");
			return -1;
		}
		
		
		while (strcmp (sv, "EXIT"))
		{
			sprintf(sv, "Received from (IP = %s port %u):\n >> ", inet_ntoa (adress.sin_addr), adress.sin_port);
			
			memset (cl, SIZE, 0);
			read(client_sockfd, &cl, SIZE );
			
			
			strcat (sv, cl);
			printf ("sv %s", sv);
			write(client_sockfd, &sv, SIZE);
			
			printf ("client (%s): %s \n", inet_ntoa (adress.sin_addr), cl);
			if (!strcmp("EXIT", cl))
			{
				memset (sv, 0, SIZE);
				strcpy(sv, "GOODBYE");
				write(client_sockfd, &sv, SIZE);
			}
			else
				write(client_sockfd, &sv, SIZE);
		}
	}
	else
		close(client_sockfd);
		
	};
	
	return 0;
	
}
